#ifndef __GLF_FVECTOR_H_INCLUDED__
#define __GLF_FVECTOR_H_INCLUDED__

//TODO finish implementing fvector
//TODO add template param to support object alignment

#include <glf/config.h>
#include <glf/fstl/fstl.h>
#include <glf/fstl/fallocator.h>

#include <vector>

namespace glf {

template<typename T, size_t SIZE, size_t ALIGN=sizeof(T)>
struct fvector : public std::vector<T, fixed_alloc<T> >
{
	typedef fixed_alloc<T>			my_alloc;
	typedef std::vector<T, my_alloc>	my_parent;
	typedef fvector<T, SIZE, ALIGN>	my_type;
	
	fvector() : 
		my_parent(my_alloc(mAllocInfo, mBuffer, sizeof(mBuffer)))
#if GLF_CONFIG_DEBUG
		, mDbgCapacity(SIZE)
		, mDbgElems(reinterpret_cast<T (*)[SIZE]>(mBuffer))
#endif
	{
		my_parent::reserve(SIZE);
	}

	fvector(size_t count) : 
		my_parent(count, T(), my_alloc(mAllocInfo, mBuffer, sizeof(mBuffer)))
#if GLF_CONFIG_DEBUG
		, mDbgCapacity(SIZE)
		, mDbgElems(reinterpret_cast<T (*)[SIZE]>(mBuffer))
#endif
	{
		my_parent::reserve(SIZE);
	}

	fvector(const my_type& s) :
		my_parent(my_alloc(mAllocInfo, mBuffer, sizeof(mBuffer)))
#if GLF_CONFIG_DEBUG
		, mDbgCapacity(SIZE+1)
		, mDbgElems(reinterpret_cast<T (*)[SIZE]>(mBuffer))
#endif
	{
		my_parent::reserve(SIZE);
		assign(s.begin(), s.end());
	}

	template<typename T, size_t OTHER_SIZE, size_t OTHER_ALIGN>
	fvector(const fvector<T, OTHER_SIZE, OTHER_ALIGN>& s) :
		my_parent(my_alloc(mAllocInfo, mBuffer, sizeof(mBuffer)))
#if GLF_CONFIG_DEBUG
		, mDbgCapacity(SIZE+1)
		, mDbgElems(reinterpret_cast<T (*)[SIZE]>(mBuffer))
#endif
	{
		my_parent::reserve(SIZE);
		assign(s.begin(), s.end());
	}

	~fvector() { 
		my_parent::~my_parent();
	}

	my_type& operator=(const my_type& other) {
		if(this != &other) {
			resize(0);
			assign(other.begin(), other.end());
			//my_parent::operator=(other);
		}
		return *this;
	}
private:
	static void* operator new(size_t s);
	static void* operator new[](size_t s);
	static void  operator delete(void*) {}
	static void  operator delete[](void*){}

	void reserve(size_t);
	
	char mBuffer[SIZE * sizeof(T) + 4];

	fixed_alloc_info mAllocInfo;

#if GLF_CONFIG_DEBUG	
	const int mDbgCapacity;
	T (*mDbgElems)[SIZE];
#endif
};

} //namespace glf
#endif

